﻿#region Copyright (c) 2003 - 2008, Andreas Mueller
/////////////////////////////////////////////////////////////////////////////////////////
// 
// Copyright (c) 2003 - 2008, Andreas Mueller.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
//    Andreas Mueller - initial API and implementation
//
// 
// This software is derived from software bearing the following
// restrictions:
// 
// Copyright (c) 1994
// Hewlett-Packard Company
// 
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation.  Hewlett-Packard Company makes no
// representations about the suitability of this software for any
// purpose.  It is provided "as is" without express or implied warranty.
// 
// 
// Copyright (c) 1996,1997
// Silicon Graphics Computer Systems, Inc.
// 
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation.  Silicon Graphics makes no
// representations about the suitability of this software for any
// purpose.  It is provided "as is" without express or implied warranty.
// 
// 
// (C) Copyright Nicolai M. Josuttis 1999.
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// 
/////////////////////////////////////////////////////////////////////////////////////////
#endregion


using NStl.Iterators;
using NStl.Iterators.Support;
using NStl.Linq;
using NUnit.Framework;
using System.Collections.Generic;
using System.Collections;
using NUnit.Framework.SyntaxHelpers;


namespace NStl.NUnit.Linq.ListTExtensions
{
    [TestFixture]
    public class ListTExtensionFixture
    {
        [Test]
        public void InsertIterator()
        {
            List<int> v = new List<int>(new[] { 0, 1, 2, 3 });
            IEnumerable<int> toInsert = new[] { 11, 12, 13 };

            ListTIterator<int> insertAt = v.Begin() + 2;
            IOutputIterator<int> insertionIt = v.InsertIterator(insertAt);

            Algorithm.Copy(toInsert.Begin(), toInsert.End(), insertionIt);

            ICollection expected = new[] { 0, 1, 13, 12, 11, 2, 3 };

            CollectionAssert.AreEqual(expected, v);
        }
        
        [Test]
        public void Erase()
        {
            List<int> list = new List<int>{0, 1, 2, 3, 4};


            // erase the last
            ListTIterator<int> last = list.End() - 1;
            ListTIterator<int> pos = list.Remove(last);

            Assert.That(pos, Is.EqualTo(list.End()));

            ICollection expected = new[] { 0, 1, 2, 3 };
            CollectionAssert.AreEqual(expected, list);
        }
        [Test]
        public void EraseRange()
        {
            List<int> list = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });


            ListTIterator<int> pos =
                list.Remove(list.Begin() + 1, list.Begin() + 3);

            Assert.That(pos, Is.EqualTo(list.Begin() + 1));
            Assert.That(pos.Value, Is.EqualTo(3));

            ICollection expected = new[] { 0, 3, 4, 5, 6, 7, 8, 9 };
            CollectionAssert.AreEqual(expected, list);
        }



        [Test]
        public void InsertBegin()
        {
            List<int> v = new List<int>(new[]{0, 1, 2, 3});
            ListTIterator<int> insertAt = v.Begin();
            ListTIterator<int> insertedAt =
                v.Insert(insertAt, 2);

            Assert.AreEqual(insertAt, insertedAt);

            ICollection expected = new[] { 2, 0, 1, 2, 3 };

            CollectionAssert.AreEqual(expected, v);
        }
        [Test]
        public void InsertOnEmpty()
        {
            List<int> v = new List<int>();
            ListTIterator<int> insertAt = v.Begin();
            ListTIterator<int> insertedAt =
                v.Insert(insertAt, 2);

            Assert.AreEqual(insertAt, insertedAt);

            ICollection expected = new[] { 2 };

            Assert.That(v, Is.EqualTo(expected));
        }
        [Test]
        public void Insert()
        {
            List<int> v = new List<int>(new[]{0, 1, 2, 3});
            ListTIterator<int> insertAt = v.Begin() + 2;

            ListTIterator<int> insertedAt =
                v.Insert(insertAt, 2);
            Assert.AreEqual(insertAt, insertedAt);

            ICollection expected = new[] { 0, 1, 2, 2, 3 };

            CollectionAssert.AreEqual(expected, v);
        }
        [Test]
        public void InsertWithCount()
        {
            List<int> v = new List<int>(new[] { 0, 1, 2, 3 });
            ListTIterator<int> insertAt = v.Begin() + 2;

            ListTIterator<int> insertedAt = 
                v.Insert(insertAt, 2, 42);

            Assert.AreEqual(insertAt, insertedAt);

            ICollection expected = new[] { 0, 1, 42, 42, 2, 3 };

            CollectionAssert.AreEqual(expected, v);
        }
        [Test]
        public void InsertWithCountOf0()
        {
            List<int> v = new List<int>(new[] { 0, 1, 2, 3 });
            ListTIterator<int> insertAt = v.Begin() + 2;

            ListTIterator<int> insertedAt =
                v.Insert(insertAt, 0, 42);

            Assert.AreEqual(insertAt, insertedAt);

            ICollection expected = new[] { 0, 1, 2, 3 };

            CollectionAssert.AreEqual(expected, v);
        }
        [Test]
        public void InsertEnd()
        {
            List<int> v = new List<int>(new[] { 0, 1, 2, 3 });
            ListTIterator<int> insertAt = v.End();

            ListTIterator<int> insertedAt =
                v.Insert(insertAt, 2);

            Assert.AreEqual(insertAt, insertedAt);
            Assert.AreNotEqual(v.End(), insertedAt);// check this :-)

            ICollection expected = new[] { 0, 1, 2, 3, 2 };

            CollectionAssert.AreEqual(expected, v);
        }
        [Test]
        public void ReverseIterators()
        {
            List<int> v = new List<int>(new[] { 0, 1, 2, 3 });
            LinkedList<int> target = new LinkedList<int>(new[] {0, 0, 0, 0});
            ICollection expected = new[] {3, 2, 1, 0};

            Algorithm.Copy(v.RBegin(), v.REnd(), target.Begin());

            CollectionAssert.AreEqual(expected, target);
        }
    }
}
